package ve.edu.ucla.laboratorio.dals.modelo;

import java.util.Collections;
import java.util.Date;
import java.util.List;

import ve.edu.ucla.laboratorio.dals.Utilidades;

public class Autenticacion {
	private static Autenticacion ultimaAutenticacion = null;
	
	private final String nombre;
	private final List<Permiso> permisos;
	private final EstadoAutenticacion estado;
	private final Date fechaCaducacion;
	
	private Autenticacion(String nombre, List<Permiso> permisos, Date fechaCaducacion) {
		super();
		this.nombre = nombre;
		this.permisos = Collections.unmodifiableList(permisos);
		this.estado = EstadoAutenticacion.VALIDO;
		this.fechaCaducacion = fechaCaducacion;
	}

	private Autenticacion(String nombre, List<Permiso> permisos, EstadoAutenticacion estado, Date fechaCaducacion) {
		super();
		this.nombre = nombre;
		this.permisos = Collections.unmodifiableList(permisos);
		this.estado = estado;
		this.fechaCaducacion = fechaCaducacion;
	}
	
	public Autenticacion(EstadoAutenticacion estadoAutenticacion) {
		this.nombre = null;
		this.permisos = Collections.emptyList();
		this.estado = estadoAutenticacion;
		this.fechaCaducacion = null;
	}

	public String getNombre() {
		return nombre;
	}

	public List<Permiso> getPermisos() {
		return permisos;
	}
	
	public boolean contienePermiso(Permiso permiso) {
		return permisos.contains(permiso);
	}
	
	public static Autenticacion error(EstadoAutenticacion estadoAutenticacion) {
		return new Autenticacion(estadoAutenticacion);
	}

	public static Autenticacion exitoso(String nombre, List<Permiso> permisos, Date fechaCaducacion) {
		return new Autenticacion(nombre, permisos, fechaCaducacion);
	}

	public EstadoAutenticacion getEstado() {
		return estado;
	}

	public static Autenticacion autenticar(RepositorioUsuarios repositorio, String nombre, String clave) {
		String mensaje = codificarClave(nombre, clave);
		ultimaAutenticacion = repositorio.autenticar(nombre, Utilidades.convertirMD5(mensaje));
		return ultimaAutenticacion;
	}
	
	public static String codificarClave(String nombre, String clave) {
		return String.format("%s(%s)", nombre, clave);
	}

	public Date getFechaCaducacion() {
		return fechaCaducacion;
	}
	
	public static Autenticacion estadoActual(RepositorioUsuarios repositorio, Preferencias preferencias) {
		if (ultimaAutenticacion == null) {
			return cargarAutenticacion(repositorio, preferencias);
		}
		
		Date fechaCaducacion = ultimaAutenticacion.getFechaCaducacion();
		if (fechaCaducacion == null || fechaCaducacion.compareTo(new Date()) < 0) {
			return cargarAutenticacion(repositorio, preferencias);
		}
		
		return ultimaAutenticacion;
	}

	private static Autenticacion cargarAutenticacion(RepositorioUsuarios repositorio, Preferencias preferencias) {
		String nombreUsuario = preferencias.getAutenticacionNombreUsuario();
		Date caducacion = preferencias.getAutenticacionFechaCaducacion();
		if (caducacion != null && caducacion.compareTo(new Date()) >= 0) {
			ultimaAutenticacion = new Autenticacion(
					preferencias.getAutenticacionNombreUsuario(),
					preferencias.getAutenticacionListadoPermisos(),
					preferencias.getAutenticacionEstado(),
					preferencias.getAutenticacionFechaCaducacion());
		} else {
			ultimaAutenticacion = Autenticacion.error(EstadoAutenticacion.NO_AUTENTICADO);
		}
		
		return ultimaAutenticacion;
	}
}
